package controllers

import (
	//	"bufio"
	//	"fmt"
	// "io/ioutil"
	"net/http"
	"strings"
	//"labix.org/v2/mgo/bson"
	// "golanger.com/log"
	"encoding/json"
	"golanger.com/utils"
	"helper"
	"io/ioutil"
	"jk/jklog"
	"models"
	"time"
)

type PageJmdkina struct {
	Application
}

func init() {
	App.RegisterController("jmdkina/", PageJmdkina{})
}

func (p *PageJmdkina) Before_() []map[string]string {
	return []map[string]string{
		map[string]string{
			"_FILTER": "getIndex",
			"_ALL":    "allow",
			"Index":   "deny",
		},
		map[string]string{
			"_FILTER":  "GetTest",
			"TestPage": "allow",
		},
		map[string]string{
			"_FILTER":  "GetTest1",
			"TestPage": "allow",
			"Index":    "allow",
		},
	}
}

func (p *PageJmdkina) After_() []map[string]string {
	return []map[string]string{
		map[string]string{
			"_FILTER":  "after",
			"_ALL":     "allow",
			"TestPage": "deny",
		},
	}
}

func (p *PageJmdkina) After_Index(w http.ResponseWriter, r *http.Request) {
	//	fmt.Println("After_Index")
}

type FileName struct {
	Name    string
	ImgPath string
}

type FileNames struct {
	Files   []FileName
	Time    string
	Title   string
	Content string
}

func dealInvite(ip, userAgent string) utils.M {
	inviteQuery := utils.M{
		"Ip":        ip,
		"UserAgent": userAgent,
	}
	inviteBack := utils.M{}

	invites := models.NewInvite()
	jklog.L().Infoln("The Total invites : ", invites.JKInviteCounts())

	// If this ip is exist
	exist := invites.JKInviteExist(inviteQuery)
	// If not exist, insert it
	if exist == false {
		inviteQuery["FirstInviteTime"] = time.Now().Unix()
		inviteQuery["LastInviteTime"] = time.Now().Unix()
		inviteQuery["UserAgent"] = userAgent
		inviteQuery["Index"] = invites.JKInviteCounts() + 1
		inviteQuery["InIndex"] = 1
		err := invites.JKInviteInsert(inviteQuery)
		if err != nil {
			jklog.L().Errorln("insert error ", err)
		}
		inviteBack = inviteQuery // first invite equal with inviteQuery
	} else {
		invites.JKInviteQuery(inviteQuery, inviteBack)
		var invitesInter models.JKInviteItem
		inviteBack.MapToStruct(&invitesInter)
		inIndex := invitesInter.InIndex
		inviteUpdate := utils.M{
			"Ip":             ip,
			"UserAgent":      userAgent,
			"LastInviteTime": time.Now().Unix(),
			"InIndex":        inIndex + 1,
		}
		err := invites.JKInviteUpdate(inviteQuery, inviteUpdate)
		if err != nil {
			jklog.L().Errorln("update err", err)
		}
	}
	return inviteBack
}

func (p *PageJmdkina) Index(w http.ResponseWriter, r *http.Request) {

	var imgs []models.Path
	if err := models.GetImages(nil, &imgs); err != nil {
		jklog.L().Errorln("No Images")
	}

	userAgent := r.UserAgent()

	remote := strings.Split(r.RemoteAddr, ":")

	inviteBack := dealInvite(remote[0], userAgent)

	body := utils.M{}
	body["imgs"] = imgs
	body["invite"] = inviteBack
	p.Body = body
}

func (p *PageJmdkina) Onelist(w http.ResponseWriter, r *http.Request) {

	tofindname := p.POST["tofindname"]
	if tofindname == "" {
		return
	}

	var imgs []models.Path
	if err := models.GetImages(nil, &imgs); err != nil {
		jklog.L().Errorln("No Images")
	}

	var onelistimg []models.Image
	for _, v := range imgs {
		if v.Title == tofindname {
			// find it
			jklog.L().Infoln("OK, find one", v.Title)
			onelistimg = v.Images
		}
	}

	body := utils.M{}
	body["onelist"] = onelistimg
	p.Body = body
}

func (p *PageJmdkina) List(w http.ResponseWriter, r *http.Request) {

	var imgs []models.Path
	if err := models.GetImages(nil, &imgs); err != nil {
		jklog.L().Errorln("No Images")
	}

	body := utils.M{}
	body["imgs"] = imgs
	p.Body = body
}

func (p *PageJmdkina) Jkadd(rw http.ResponseWriter, req *http.Request) {
	p.Document.Title = "添加条目"
}

func (p *PageJmdkina) Help(rw http.ResponseWriter, req *http.Request) {

}

func transPathToTitle(path string) string {
	if strings.Index(path, "/") >= 0 {
		return strings.Replace(path, "/", "-", -1)
	}
	return path
}

func transPathToDirStyle(path string) string {
	if strings.Index(path, "-") > 0 {
		tmp := strings.Replace(path, "-", "/", -1)
		return strings.Replace(tmp, "/0", "/", -1)
	}
	return path
}

func (p *PageJmdkina) DelItem(w http.ResponseWriter, r *http.Request) {
	status := utils.M{
		"status": helper.JK_RESULT_SUCCESS,
	}
	if r.Method == "POST" {
		if _, bok := p.POST["jk"]; bok {
			title := p.POST["title"]
			code := p.POST["code"]
			// time := p.POST["createtime"]

			if code != "jkdel0702" {
				status["status"] = helper.JK_RESULT_E_CODE_ERROR
				goto out
			}
			// compare by createtime to del
			query := utils.M{
				"path": title,
			}

			if models.ImageExist(query) <= 0 {
				status["status"] = helper.JK_RESULT_E_NOT_EXIST
				goto out
			}
			if models.ImagesRemove(query) != nil {
				jklog.L().Infoln("remove error ", nil)
				status["status"] = helper.JK_RESULT_E_DATABASE_REMOVE_ERROR
				goto out
			}

		} else {
			status["status"] = helper.JK_RESULT_E_PARAM_ERROR
			goto out
		}
	}

out:
	result, _ := json.Marshal(status)
	w.Write(result)
}

func (p *PageJmdkina) AddItem(w http.ResponseWriter, r *http.Request) {
	status := utils.M{
		"status": helper.JK_RESULT_SUCCESS,
	}
	if r.Method == "POST" {
		if _, bok := p.POST["jk"]; bok {
			pathname := p.POST["title"]
			author := p.POST["author"]
			content := p.POST["content"]
			createtime := time.Now().Unix()
			updatetime := time.Now().Unix()

			code := p.POST["code"]
			if code != "jkadd0702" {
				status["status"] = helper.JK_RESULT_E_CODE_ERROR
				goto out
			}

			if len(pathname) == 0 {
				pathname = "default"
			}

			// basic info of path
			path := models.Path{
				Path:       transPathToDirStyle(pathname),
				Cover:      "",
				Isdir:      true,
				Author:     author,
				Title:      pathname, // name to display of time
				Content:    content,
				CreateTime: createtime,
				UpdateTime: updatetime,
			}

			query := utils.M{
				"path": path.Path,
			}

			if models.ImageExist(query) > 0 {
				// remove it if has exist use for mod
				jklog.L().Infoln(path.Path, " is exist, so first remove it")
				if models.ImagesRemove(query) != nil {
					status["status"] = helper.JK_RESULT_E_DATABASE_REMOVE_ERROR
					goto out
				}
			}

			/* now we need set each image info use read from path */
			files, err := ioutil.ReadDir(helper.GetPicsBasicPath() + "/" + path.Path)
			jklog.L().Infoln("read dir ", path.Path, ", result len ", len(files))
			if err == nil && len(files) > 0 {

				for _, file := range files {
					if file.IsDir() {
						// max support two level images
						files, err := ioutil.ReadDir(helper.GetPicsBasicPath() + "/" + path.Path + "/" + file.Name())
						if err == nil && len(files) > 0 {
							if path.Cover == "" {
								path.Cover = path.Path + "/" + file.Name() + "/" + files[0].Name()
							}
							for _, infile := range files {
								// just deal files, ignore dirs
								if !infile.IsDir() {
									image := models.Image{
										Path:       path.Path + "/" + file.Name() + "/" + infile.Name(),
										Name:       infile.Name(),
										Author:     author,
										Content:    "",
										CreateTime: time.Now().Unix(),
										UpdateTime: time.Now().Unix(),
									}
									path.Images = append(path.Images, image)
								}
							}
						}
					} else {
						if strings.HasPrefix(file.Name(), ".") {
							continue
						}
						// default set first image to cover
						if path.Cover == "" {
							path.Cover = path.Path + "/" + file.Name()
						}
						// add images
						image := models.Image{
							Path:       path.Path + "/" + file.Name(),
							Name:       file.Name(),
							Author:     author,
							Content:    "",
							CreateTime: time.Now().Unix(),
							UpdateTime: time.Now().Unix(),
						}
						path.Images = append(path.Images, image)
					}
				}

				if models.ImagesInsert(path) != nil {
					status["status"] = helper.JK_RESULT_E_DATABASE_INSERT_ERROR
				}
			} else {
				status["status"] = helper.JK_RESULT_E_DATA_NOT_EXIST
			}

		} else {
			status["status"] = helper.JK_RESULT_E_PARAM_ERROR
		}
	}
out:
	result, _ := json.Marshal(status)
	w.Write(result)
}
